﻿Imports System.IO
Imports System.Runtime.Serialization

Imports IntoNails.Models

<Serializable()> _
Public Class NailCategoryRepository
    Inherits AbstractFileRepository(Of NailCategory)
    Implements INailCategoryRepository, ISerializable

#Region "Constructors"

    Public Sub New(ByVal dataFile As String)
        Me.DataFile = dataFile
        Me.Load()
    End Sub

    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        Me.InnerDataList = DirectCast(info.GetValue("NailCategoryList", GetType(List(Of NailCategory))), List(Of NailCategory))
    End Sub

    Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal ctxt As StreamingContext) _
        Implements ISerializable.GetObjectData
        info.AddValue("NailCategoryList", Me.InnerDataList)
    End Sub

#End Region

    Public Overrides Sub Load()
        If IO.File.Exists(Me.DataFile) Then
            Using readStream As New FileStream(Me.DataFile, FileMode.Open, FileAccess.Read)
                Me.InnerDataList = readStream.Deserialize(Of List(Of NailCategory))()
            End Using
        Else
            Me.InnerDataList = New List(Of NailCategory)()
        End If
    End Sub

    Public Overrides Sub Save()
        Using writeStream As New FileStream(Me.DataFile, FileMode.OpenOrCreate, FileAccess.Write)
            Me.InnerDataList.Serialize(writeStream)
        End Using
    End Sub

    Public Function Add(ByVal data As NailCategory) As Boolean _
        Implements IDataRepository(Of NailCategory).Add

        Dim result As Boolean = False

        If Not Me.InnerDataList.Contains(data) Then
            Me.InnerDataList.Add(data)

            result = True
        End If

        Dim addedArgs As DataEventArgs(Of NailCategory) = New DataEventArgs(Of NailCategory)(data, result)
        Me.OnDataAdded(addedArgs)

        Return result
    End Function

    Public Function GetItem(ByVal uniqueCode As Integer) As NailCategory _
        Implements IDataRepository(Of NailCategory).GetItem

        Return Me.InnerDataList.Where(Function(ns) ns.UniqueCode = uniqueCode).FirstOrDefault()
    End Function

    Public Function GetRawCollection() As List(Of NailCategory) _
        Implements IDataRepository(Of NailCategory).GetRawCollection

        Return Me.InnerDataList
    End Function

    Public Function Remove(ByVal uniqueCode As Integer) As Boolean _
        Implements IDataRepository(Of NailCategory).Remove

        Dim result As Boolean = False
        Dim removedItem As NailCategory = Me.GetItem(uniqueCode)

        If removedItem IsNot Nothing Then
            removedItem.IsValid = False
            removedItem.DateChanged = Date.Today

            result = True
        End If

        Dim removedArgs As DataEventArgs(Of NailCategory) = New DataEventArgs(Of NailCategory)(removedItem, result)
        Me.OnDataRemoved(removedArgs)

        Return result
    End Function

    Public Function Update(ByVal uniqueCode As Integer, ByVal newData As NailCategory) As Boolean _
        Implements IDataRepository(Of NailCategory).Update

        Dim result As Boolean = False
        Dim updatedItem As NailCategory = Me.GetItem(uniqueCode)
        If updatedItem IsNot Nothing AndAlso newData IsNot Nothing Then
            With updatedItem
                updatedItem.Name = newData.Name
                updatedItem.IsValid = newData.IsValid
                updatedItem.DateChanged = Date.Today
            End With

            result = True
        End If

        Dim updatedArgs As DataUpdatedEventArgs(Of NailCategory) = New DataUpdatedEventArgs(Of NailCategory)(updatedItem, newData, result)
        Me.OnDataUpdated(updatedArgs)

        Return result
    End Function

    Public Function GetNailCategory(ByVal name As String) As NailCategory _
        Implements INailCategoryRepository.GetNailCategory

        Return Me.InnerDataList.Where(Function(ns) ns.Name.ToUpper().Trim() = name.ToUpper().Trim()).FirstOrDefault()
    End Function

    Public Function GetSubCategory(ByVal parentCode As Integer) As List(Of NailCategory) _
        Implements INailCategoryRepository.GetSubCategory

        Return Me.InnerDataList.Where(Function(c) c.ParentCode = parentCode).ToList()
    End Function

    Public Function GetValidNailCategoryCollection() As List(Of Models.NailCategory) _
        Implements INailCategoryRepository.GetValidNailCategoryCollection

        Return Me.InnerDataList.Where(Function(ns) ns.IsValid = True).ToList()
    End Function

End Class
